﻿using Shinva.Variables.Interface;
using Shinva.Variables.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Shinva.Variables.Models
{

    /// <summary>
    /// 这是变量表接口,比如Contact 的operand 接口就会存到这里的Dictionary中
    /// </summary>
    public class VariableTableInterface
    {
        private Dictionary<string, VariablePointer> _variables = new Dictionary<string, VariablePointer>();

        /// <summary>
        /// 设置或者改变接口中的变量实例
        /// </summary>
        /// <param name="name"></param>
        /// <param name="type"></param>
        /// <param name="value"></param>
        public bool SetVariable(string name, IPlcMember value = null)
        {
            if (_variables.ContainsKey(name))
            {
                _variables[name] = new VariablePointer(_variables[name].Type, value);
                return true;
            }
            else
            {
                return false; // 如果不存在，返回false
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="type"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool AddVariable(string name, StorageType type, IPlcMember value = null)
        {
            if (_variables.ContainsKey(name))
            {
                return false; // 如果已经存在，返回false

            }
            else
            {
                _variables[name] = new VariablePointer(type, value);
                return true; // 如果不存在，添加并返回true
            }
        }
        /// <summary>
        /// 获取接口中的变量实例
        /// </summary>
        /// <typeparam name="IPlcMember"></typeparam>
        /// <param name="name"></param>
        /// <returns></returns>
        /// <exception cref="InvalidCastException"></exception>
        public IPlcMember GetVariableValue<IPlcMember>(string name)
        {
            if (_variables.TryGetValue(name, out var variable) && variable.Value is IPlcMember typedValue)
            {
                return typedValue;
            }
            else
            {
                return default; // 使用 default(IPlcMember) 以解决 CS0403 错误

            }

        }
        public bool ContainsKey(string name)
        {
            return _variables.ContainsKey(name);
        }

        /// <summary>
        /// 根据接口中的存储类型获取变量实例，
        /// input、output、inout、static、constant、temp、return等，获取接口中所有的变量实例
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public IEnumerable<IPlcMember> GetVariablesByStorageType(StorageType type)
        {
            return (IEnumerable<IPlcMember>)_variables.Values.Where(v => v.Type == type);
        }

    }
}
